#include <ctime>
#include <cstdlib>

#include <iostream>

#include "Protocol.hpp"
#include "Service.hpp"
#include "Socket.hpp"
#include "Log.hpp"

using namespace socket_ddsm;

const static std::string randOper = "+-*/%!@#";

int main(int args, char *argv[])
{
    if (args != 3)
    {
        std::cerr << "Usage:" << argv[0] << "Server ip" << "Server port" << std::endl;
    }

    std::string serverip = argv[1];
    uint16_t serverport = std::stoi(argv[2]);

    SockSPtr sock = std::make_shared<TcpSocket>();
    if (sock->BuildClientSocket(serverip, serverport))
    {
        std::cerr << "connect error" << std::endl;
        exit(1);
    }

    srand((unsigned int)time(nullptr));
    std::string packagestream;
    while (true)
    {
        // 1.构建Request
        int x = rand() % 10;
        usleep(x * 100);
        int y = rand() % 10;
        usleep(x * y * 19);
        char oper = randOper[y % randOper.size()];
        auto requ = Factory::BuildRequestDefault();
        requ->SetValue(x, y, oper);

        // 2.序列化请求,得到json串
        std::string jsonstr;
        requ->Serialize(&jsonstr);

        // 3.添加长度和报头字段，得到完整的报文
        jsonstr = EnCode(jsonstr);

        std::cout<<"Request:"<<jsonstr<<std::endl;

        // 4.发送报文
        sock->Send(jsonstr);

        while (true)
        {
            // 5.读取应答 Response,接受完整的报文

            ssize_t n = sock->Recv(&packagestream);
            if (n <= 0)
            {
                break;
            }
            //6.报文解析，提取报头和有效载荷
            std::string package = DeCode(packagestream);
            // 如果报文不完整则退出循环
            if (package.empty())
                continue;

            //7.反序列化
            auto resp = Factory::BuildResponseDefault();
            resp->Deserialize(package);
            resp->Print();
        }
    }

    return 0;
}
